package com.oauth.facebook.server;

import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;

import com.oauth.common.server.OAuthGwtController;
import com.oauth.common.server.beans.OAuthAccessToken;
import com.oauth.common.server.util.OAuthRequestUtil;
import com.oauth.components.client.beans.OAuthUrl;
import com.oauth.components.client.rpc.exception.SessionExpiredException;
import com.oauth.facebook.client.beans.FacebookModel;
import com.oauth.facebook.client.beans.FacebookUser;
import com.oauth.facebook.client.beans.LinkedinOAuthVerifier;
import com.oauth.facebook.client.exception.FacebookOAuthException;
import com.oauth.facebook.client.rpc.FacebookRemoteService;
import com.oauth.facebook.server.beans.FacebookRequestToken;
import com.oauth.facebook.server.constants.FacebookConstants;
import com.oauth.facebook.server.service.FacebookService;

public class FacebookGwtController extends OAuthGwtController implements FacebookRemoteService {

	private Logger logger = Logger.getLogger(this.getClass());
	private static final long serialVersionUID = -5758464341967618224L;

	private FacebookService mFacebookService;

	/**
	 * @param pFacebookService
	 *            the facebookService to set
	 */
	@Autowired
	public void setFacebookService(FacebookService pFacebookService) {
		mFacebookService = pFacebookService;
	}

	@Override
	public OAuthUrl getSignInUrl() throws FacebookOAuthException {
		FacebookRequestToken requestToken;
		try {
			requestToken = mFacebookService.getRequestToken();
		} catch (Exception e) {
			logger.error("Error in getting request token", e);
			throw new FacebookOAuthException();
		}
		OAuthRequestUtil.createTokenCookies(getHttpResponse(), requestToken,
				FacebookConstants.FACEBOOK_TOKEN_COOKIE,
				FacebookConstants.FACEBOOK_TOKEN_SECRETCOOKIE);
		OAuthUrl oauthUrl = new OAuthUrl();
		oauthUrl.setOAuthUrl(requestToken.getAuthorizeUrl());
		return oauthUrl;
	}

	public List<FacebookUser> getConnections() throws FacebookOAuthException {
		try {
			Long memberId = OAuthRequestUtil.getMemberId(getHttpRequest());
			List<FacebookUser> connections = mFacebookService.getFriends(memberId);
			return connections;
		} catch (Exception e) {
			logger.error("Error in fetching scraps", e);
			throw new FacebookOAuthException();
		}
	}

	public FacebookModel getLinkedInData(LinkedinOAuthVerifier pOAuthVerifier)
			throws FacebookOAuthException {
		FacebookModel model = new FacebookModel();

		logger.info("Entering facebook home controller");

		Long memberId = OAuthRequestUtil.getMemberId(getHttpRequest());
		try {
			OAuthAccessToken accessToken = mFacebookService.getAccessTokenFromDB(memberId);
			if (accessToken == null) {
				/* Get request token from cookie. */
				/*
				 * Since there is no request token for facebook.Go directly
				 * check verifier
				 */

				if (pOAuthVerifier != null && isEmpty(pOAuthVerifier.getOAuthVerifier())) {
					model.setLoginView(true);
					return model;// Go to login page, as there is no access
					// token in
					// db and no cookie.
				} else {
					System.out.println("code=" + pOAuthVerifier.getOAuthVerifier());
					accessToken = mFacebookService.getAccessTokenFromRequestToken(null,
							pOAuthVerifier.getOAuthVerifier());

					/* Store access token for future use */
					mFacebookService.persistAccessToken(accessToken, memberId);
					deleteCookies();
				}
			}
		} catch (Exception e) {
			deleteCookies();
			logger.error("Error in fetching facebook home data", e);
			e.printStackTrace();
			model.setLoginView(true);
			return model;// Go to login page, as there is no access
		}

		// finally you got the access token which is stored in db.
		FacebookUser user;
		try {
			user = getLoggedInUserInfo();
		} catch (Exception e) {
			logger.error("Error in fetching facebook home data", e);
			e.printStackTrace();
			throw new FacebookOAuthException();
		}
		model.setUser(user);
		return model;

	}

	private boolean isEmpty(String pOAuthVerifier) {
		return pOAuthVerifier == null || pOAuthVerifier.length() == 0;
	}

	public FacebookUser getLoggedInUserInfo() throws Exception {
		Long memberId = OAuthRequestUtil.getMemberId(getHttpRequest());
		FacebookUser profile = mFacebookService.getFacebookUser(memberId);
		return profile;
	}

	private void deleteCookies() {
		OAuthRequestUtil.deleteTokenCookies(getHttpResponse(),
				FacebookConstants.FACEBOOK_TOKEN_COOKIE,
				FacebookConstants.FACEBOOK_TOKEN_SECRETCOOKIE);
	}

	@Override
	public List<FacebookUser> getUpdates() throws SessionExpiredException, FacebookOAuthException {
		Long memberId = OAuthRequestUtil.getMemberId(getHttpRequest());
		try {
			return mFacebookService.getUpdates(memberId);
		} catch (Exception e) {
			logger.error(e);
			e.printStackTrace();
			throw new FacebookOAuthException();
		}
	}

	@Override
	public boolean updateStatus(String pText) throws SessionExpiredException,
			FacebookOAuthException {
		try {
			Long memberId = OAuthRequestUtil.getMemberId(getHttpRequest());
			mFacebookService.updateStatus(pText, memberId);
			return true;
		} catch (Exception e) {
			logger.error("Error in fetching scraps", e);
			throw new FacebookOAuthException();
		}

	}

}
